Universo Online
Web Sites Pessoais
Anterior Próximo Índice

Chamando uma Rotina Próxima em Assembly a partir do Turbo C.

Há apenas duas diferenças notáveis entre uma rotina assembly para o Turbo Pascal e uma para o Turbo C: 1) os parâmetros para a linguagem C são empilhados da direita para a esquerda, ou seja, o último parâmetro é empilhado primeiro; 2) o compilador C se encarrega de retirar os parâmetros da pilha, então você termina a rotina apenas fazendo um RET normal (FAR ou NEAR), sem operandos. Alguns compiladores exigem que você salve pelo menos os registradores ponteiros SI e DI (se usados na rotina). Uma rotina para o Turbo Pascal exige que seja salvo pelo menos o registor DS. É aconselhável, entretanto, salvar todos os registrados de segmento usados. Outras exigências para a maioria dos compiladores C: uma rotina ou variável pública (PUBLIC ou GLOBAL) deve ter o carácter "_" no início do nome, e o ligador é sensível a letras maiúsculas e minúsculas (_Funcao é diferente de _funcao para ele).

Configuração da pilha para o modelo pequeno de memória (SMALL):

SP      =  Valor Inicial de SP
SP - 02 = Valor de SP após empilhar o terceiro parâmetro
SP - 04 = Valor de SP após empilhar o segundo parâmetro
SP - 06 = Valor de SP após empilhar o primeiro parâmetro
SP - 08 = Valor de SP após a rotina empilhar o valor IP
SP - 10 = Valor de SP após empilhar o valor de BP
Para acessar cada parâmetro você deve considerar a seguinte aritmética:

Endereço do primeiro parâmetro em relação a SS = [BP + 04] = [(SP - 10) + 04] = [SP - 6]

Endereço do segundo parâmetro em relação a SS= [BP + 06] = [(SP - 10) + 06] = [SP - 4]

Endereço do terceiro parâmetro em relação a SS = [BP + 06] = [(SP - 10) + 08] = [SP - 2]

E como você pode constantar acima, o resultado confere com os deslocamentos esperados para cada parâmetro na pilha.

;PROCN.ASM
;DEMONSTRACAO DE UMA ROTINA COM 3 PARAMETROS
;CHAMAR DE PROGRAMA EM TURBO C
;PARA MONTAR DIGITE: nasm -fobj procn.asm
;PARA LIGAR DIGITE: tcc main.c procn.obj


segment _TEXT class=CODE align=1
;------------------------------------------------------
;extern int ParamDemo(int x,int  y,int  z);
;------------------------------------------------------
   GLOBAL _ParamDemo         

_ParamDemo:
          PUSH BP
          MOV  BP,SP
          
          MOV  AX, [BP + 04] ; AX := primeiro parametro
          ADD  AX, [BP + 06] ; soma AX com segundo parametro
          ADD  AX, [BP + 08] ; soma AX com terceiro parametro
          ;RETORNA RESULTADO EM AX
          POP BP
          RET


/* main.c - Essa é a rotina em Turbo C que chama a rotina assembly }

#include <stdio.h>
extern int ParamDemo(int x, int y, int z);

int main( )
{
 int total;
   total = ParamDemo(1,2,3);
   printf("\n1+2+3 = %d",total);
   return(0);
}

                  

Anterior Próximo Índice